package caidan.net;

import caidan.MainFrame;
import caidan.res.Resource;
import jinyilw.common.app.AppConfig;
import jinyilw.swing.FontTools;
import jinyilw.common.Operator;
import jinyilw.swing.animator.SimpleAnimator;
import jinyilw.swing.visuals.Rcomp.RDialog;
import jinyilw.swing.visuals.Rcomp.ROptionPane;
import jinyilw.swing.visuals.comp.RichTextComp;
import jinyilw.swing.visuals.window.HintWindow;
import jinyilw.tools.net.ClientTools;

import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dialog;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;

public class NetFunDialog extends RDialog
{
	private static final long serialVersionUID = -4543942095886489476L;
	private SuggestPanel suggestPanel;
	private NewFoodPanel newFoodPanel;
	private RichTextComp netSymbol;
	private SimpleAnimator connectingAnimator;
	private JButton freshButton, connectButton, setNetButton;
	private SetNetDialog setNetDialog;
	ClientTools clientTools;

	public NetFunDialog(MainFrame mainFrame, ClientTools client)
	{
		super(mainFrame);
		clientTools = client;
		init();
	}

	public NetFunDialog(Frame owner, boolean modal)
	{
		super(owner, modal);
		init();
	}

	public NetFunDialog(Dialog owner, boolean modal)
	{
		super(owner, modal);
		init();
	}

	public NetFunDialog(Window owner, String title)
	{
		super(owner, title);
		init();
	}

	private void init()
	{
		// setOpacity(0.95f);
		// setOptionStyle(10, 0.95f);
		createGUI();
		initLayout();
		initListeners();

		setWindowSymbol(netSymbol);
		setTitleHeight(38);
		setTitleFont(FontTools.getCustomFont(21));
		setTitleColor(Color.yellow);
		setTitle("网 络 功 能");
		setSection(8);
		setDefaultDimensionRatio(0.8, 0.85);
		defaultSize();
		AppConfig.addAppExitingOperator((Object o) ->
		{
			suggestPanel.writeToFile();
			newFoodPanel.writeToFile();
		});
	}

	private void createGUI()
	{
		suggestPanel = new SuggestPanel(clientTools);
		newFoodPanel = new NewFoodPanel(clientTools);
		netSymbol = new RichTextComp();
		netSymbol.setImage(Resource.netIcon);
		netSymbol.setSize(200, 20);
		netSymbol.setFont(FontTools.getLargeFont());
		netSymbol.setHorizontalAlignment(SwingConstants.LEFT);
		freshButton = new JButton("刷新网络", Resource.freshIcon);
		connectButton = new JButton("重连网络", Resource.reconnectIcon);
		setNetButton = new JButton("网络设置", Resource.setNetIcon);
	}

	private void initLayout()
	{
		Container container = new Container();
		container.setLayout(new GridLayout(1, 0, 5, 5));
		container.add(suggestPanel);
		container.add(newFoodPanel);
		add(container, BorderLayout.CENTER);
		JPanel buttonsPanel = new JPanel();
		buttonsPanel.add(freshButton);
		buttonsPanel.add(connectButton);
		buttonsPanel.add(setNetButton);
		add(buttonsPanel, BorderLayout.SOUTH);
	}

	private void initListeners()
	{
		freshButton.addActionListener((ActionEvent e) ->
		{
			if (clientTools.isConnected())
				new Thread(() ->
				{
					freshButton.setEnabled(false);
					suggestPanel.reloadDatabase();
					newFoodPanel.reloadFromNet();
					freshButton.setEnabled(true);
					HintWindow.showHint("已刷新网络！", this);
				}).start();
			else
			{
				HintWindow.showHint("未连接网络！", this);
				connectBroken();
			}
		});
		connectButton.addActionListener((ActionEvent e) ->
		{
			if (!clientTools.isConnected())
				new Thread(() ->
				{
					connecting();
					if (!clientTools.reConnect())
					{
						connectBroken();
						int c = ROptionPane.showConfirmDialog(this,
								"未能连接网络！可重新设置服务器IP或开启远程服务器。\n\n是否重新设置服务器IP？\n   ",
								"未能连接网络", JOptionPane.YES_NO_OPTION);
						if (c == 0)
							showSetNetDialog();
					}
				}).start();
			else
				HintWindow.showHint("已连接网络！", this);
		});

		setNetButton.addActionListener((ActionEvent e) ->
		{
			showSetNetDialog();
		});
	}

	private void initNet()
	{
		if (clientTools.isConnected())
		{
			connectBuild();
		} else
		{
			connectBroken();
		}
		clientTools.addReConnectRunner(() ->
		{
			connectBuild();
		});
		clientTools.addBrokenRunner(() ->
		{
			connectBroken();
		});

		suggestPanel.initNet();
		newFoodPanel.initNet();
	}

	private void showSetNetDialog()
	{
		if (setNetDialog == null)
			setNetDialog = new SetNetDialog(this);
		if (setNetDialog.isVisible())
			return;
		setNetDialog.updateContent();
		setNetDialog.setLocationRelativeTo(this);
		setNetDialog.setVisible(true);
	}

	void connecting()
	{
		connectButton.setEnabled(false);
		// netSymbol.setText("正在连接网络...");
		netSymbol.setForeground(Color.yellow);
		getConnectingAnimator().start();
	}

	void connectBuild()
	{
		if (connectingAnimator != null)
			connectingAnimator.stop();
		netSymbol.setText("已连接网络");
		netSymbol.setForeground(Color.green.darker());
		freshButton.setEnabled(true);
		connectButton.setEnabled(false);
	}
	void connectBroken()
	{
		if (connectingAnimator != null)
			connectingAnimator.stop();
		netSymbol.setText("未连接网络");
		netSymbol.setForeground(Color.red);
		freshButton.setEnabled(false);
		connectButton.setEnabled(true);
	}

	private SimpleAnimator getConnectingAnimator()
	{
		if (connectingAnimator == null)
			connectingAnimator = new SimpleAnimator(500, new Operator<Integer>()
			{
				String[] strs = {"正在连接网络", "正在连接网络.", "正在连接网络..", "正在连接网络..."};
				@Override
				public void operate(Integer o)
				{
					netSymbol.setText(strs[o % strs.length]);
				}
			});
		return connectingAnimator;
	}

	private boolean isFristOpen = true;
	@Override
	public void setVisible(boolean b)
	{
		super.setVisible(b);
		if (b)
			new Thread(() ->
			{
				if (isFristOpen)
				{
					initNet();
					isFristOpen = false;
				} else if (!clientTools.isConnected())
					clientTools.reConnect();
			}).start();
	}
}
